
#region Using Statements
using System;
using System.Collections.Generic;//using System.Xml.Serialization;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
using Microsoft.Xna.Framework.Net;
#endregion


namespace Pauliver
{
    //input shoot component goes on a weapon
    //which goes in a Holder_Weapon
    //which goes in on a players

    [Serializable]
    class Input_Shoot : Input
    {
        private const double DegreeInRadians = 0.0174532925;

        private bool PoweringShot;
        public float FiringPower
        {
            get
            {
                return FiringVelocity;
            }
        }
        protected float FiringVelocity;
        protected bool shooting;
        public bool Shooting
        {
            get
            {
                return shooting;
            }
        }
        protected bool _CanShoot;
        public virtual bool CanShoot
        {
            get
            {
                return _CanShoot;
            }
            set
            {
                if (value)
                {
                    (Parent[ComponentType.Game_Rotation] as Game_Rotation).Rotation = 0.0f;
                    PoweringShot = false;
                    FiringVelocity = 0.0f;
                }
                _CanShoot = value;
            }
        }
        public Input_Shoot()
        {
            PoweringShot = false;
            shooting = false;
            _CanShoot = false;
            base._Type = ComponentType.Input_Shoot;
            FiringVelocity = 0.0f;
        }

        public override void Update(GameTime p_time)
        {
        }

        public override void ProcessInput(PlayerIndex p_PlayerIndex)
        {
            if (shooting || _CanShoot)
            {
                base.ProcessInput(p_PlayerIndex);
            }
        }

        public override void ProcessGamePad(PlayerIndex p_PlayerIndex)
        {
            GamePad gp = PInput.Instance.GamePad(p_PlayerIndex);
            bool A_Pressed = gp.A.State == InputWrapper.ButtonState.Held;
            if (A_Pressed && !shooting)
            {
                //clear out the press of a
                {
                    bool nothing = gp.A.SinglePress;
                    A_Pressed = false;
                }

                bool HasAmmoForWeapon = false;
                {
                    WeaponObject weapon  = (Parent as WeaponObject);
                    AvailableWeaponList weaponlist = (Game1.Instance.GameManager as GameManagerTeamedInterface).CurrentUTP().AvailableWeapons;
                    HasAmmoForWeapon = !(0 == weaponlist.GetAvailable(weapon));
                }

                if (!HasAmmoForWeapon)
                {
                    Game1.Instance.AddMenu(new WeaponSelectionScreen( (Parent as WeaponObject).Player) );
                }
                else
                {
                    //deploy launching rod
                    Drawable_Sprite_Animated dsa = ((Parent as WeaponObject).Player[ComponentType.Drawable_Sprite_Animated] as Drawable_Sprite_Animated);
                    if (((Parent as WeaponObject).Player[ComponentType.Game_Facing] as Game_Facing).Facing == Facing.Left)
                    {
                        dsa.SetCurrentAnimation("ShootLeft", "AimLeft");
                        (Parent as WeaponObject).SetFacing(Facing.Left);
                    }
                    else
                        if (((Parent as WeaponObject).Player[ComponentType.Game_Facing] as Game_Facing).Facing == Facing.Right)
                        {
                            dsa.SetCurrentAnimation("ShootRight", "AimRight");
                            (Parent as WeaponObject).SetFacing(Facing.Right);
                        }
                    shooting = true;
                    if ((Parent as WeaponObject).HasRod)
                    {
                        (Parent as WeaponObject).Rod = new LaunchingRod((Parent as WeaponObject).Player);
                        Game1.Instance.GameManager.AddToSceneGraph((Parent as WeaponObject).Rod);
                    }
                    (Game1.Instance.GameManager as GameManagerTeamedInterface).SetCanChangeTeam(false);
                    EventManager.GetInstance().AddEvent(ShowLauncher, 0.8f);
                    ((Parent as WeaponObject).Player[ComponentType.Holder_Weapon] as Holder_Weapon).Deploying = true;

                    Game1.Instance.CenterOn((Parent as WeaponObject).Player.Position(), true);

                    if (NetworkManager.IsUsed)
                    {
                        if ((Game1.Instance.GameManager as GameManagerTeamedInterface).MyMachineIsActive())
                        {
                            PacketWriter pw = new PacketWriter();
                            pw.Write(NetworkManager.INT);
                            pw.Write((int)(Parent as WeaponObject).Player.GetFacing());
                            pw.Write(NetworkManager.VECTOR2);
                            pw.Write((Vector2)(Parent as WeaponObject).Player.Position());
                            NetworkManager.Instance.SendToAll(pw);
                        }
                        else
                        {
                            ((Parent as WeaponObject).Player[ComponentType.Game_Facing] as Game_Facing).Facing = (Facing)(int)NetworkManager.Instance.GetNextToken<Int32>();
                            ((Parent as WeaponObject).Player[ComponentType.Game_Position] as Game_Position).Position = (Vector2)NetworkManager.Instance.GetNextToken<Vector2>();
                        }
                    }
                }
            }
            else if (Shooting && !PoweringShot && gp.B.SinglePress)
            {
                Done();
            }
            else if (shooting)
            {
                Game1.Instance.CenterOn((Parent as WeaponObject).Player.Position(), true);
                bool PutAway = gp.B.SinglePress;
                float UpDown = gp.LeftStick.Y;
                if (UpDown != 0.0f && !PoweringShot)
                {
                    if ((Parent[ComponentType.Game_Facing] as Game_Facing).Facing == Facing.Right)
                    {
                        (Parent[ComponentType.Game_Rotation] as Game_Rotation).Rotation -= .10f * UpDown;
                        if ((Parent[ComponentType.Game_Rotation] as Game_Rotation).Rotation >= 1.5)
                        {
                            (Parent[ComponentType.Game_Rotation] as Game_Rotation).Rotation = 1.5f;
                        }
                        else
                            if ((Parent[ComponentType.Game_Rotation] as Game_Rotation).Rotation <= -1.5)
                            {
                                (Parent[ComponentType.Game_Rotation] as Game_Rotation).Rotation = -1.5f;
                            }
                    }
                    else
                        if ((Parent[ComponentType.Game_Facing] as Game_Facing).Facing == Facing.Left)
                        {
                            (Parent[ComponentType.Game_Rotation] as Game_Rotation).Rotation += .10f * UpDown;
                            if ((Parent[ComponentType.Game_Rotation] as Game_Rotation).Rotation <= -1.5)
                            {
                                (Parent[ComponentType.Game_Rotation] as Game_Rotation).Rotation = -1.5f;
                            }
                            else
                                if ((Parent[ComponentType.Game_Rotation] as Game_Rotation).Rotation >= 1.5)
                                {
                                    (Parent[ComponentType.Game_Rotation] as Game_Rotation).Rotation = 1.5f;
                                }
                        }

                    if (NetworkManager.IsUsed)
                    {
                        if ((Game1.Instance.GameManager as GameManagerTeamedInterface).MyMachineIsActive())
                        {
                            PacketWriter pw = new PacketWriter();
                            pw.Write(NetworkManager.INT);
                            pw.Write((int)(Parent as WeaponObject).Player.GetFacing());
                            pw.Write(NetworkManager.VECTOR2);
                            pw.Write((Vector2)(Parent as WeaponObject).Player.Position());
                            pw.Write(NetworkManager.DOUBLE);
                            pw.Write((double)(Parent[ComponentType.Game_Rotation] as Game_Rotation).Rotation);
                            NetworkManager.Instance.SendToAll(pw);
                        }
                        else
                        {
                            ((Parent as WeaponObject).Player[ComponentType.Game_Facing] as Game_Facing).Facing = (Facing)(int)NetworkManager.Instance.GetNextToken<Int32>();
                            ((Parent as WeaponObject).Player[ComponentType.Game_Position] as Game_Position).Position = (Vector2)NetworkManager.Instance.GetNextToken<Vector2>();
                            (Parent[ComponentType.Game_Rotation] as Game_Rotation).Rotation = (float)NetworkManager.Instance.GetNextToken<Double>();
                        }
                    }
                }
                if (A_Pressed)
                {
                    FiringVelocity += .1f;
                    PoweringShot = true;
                    {
                        //If the launcher is not yet deployed this looks bad
                        Vector2 t_PotentialHit = (Parent[ComponentType.Game_Position] as Game_Position).Position;

                        Terrain t = Game1.Instance.GameManager.Terrain;
                        Vector2 t_gravity = GravityManager.Instance.Gravity;
                        Vector2 t_power = Vector2.Zero;
                        {
                            Facing t_f = (Parent[ComponentType.Game_Facing] as Game_Facing).Facing;
                            float angle = (Parent[ComponentType.Game_Rotation] as Game_Rotation).Rotation;
                            if (t_f == Facing.Right)
                            {
                                t_power = new Vector2((float)FiringVelocity * (float)Math.Cos(angle), (float)FiringVelocity * (float)Math.Sin(angle));
                            }
                            if (t_f == Facing.Left)
                            {
                                t_power = new Vector2((float)-FiringVelocity * (float)Math.Cos(angle), (float)-FiringVelocity * (float)Math.Sin(angle));
                            }
                        }

                        while (t[(int)t_PotentialHit.X] > t_PotentialHit.Y)
                        {
                            t_power += t_gravity;
                            t_PotentialHit += t_power;
                        }
                        int total = 0;
                        for (int i = -10; i <= 10; ++i)
                        {
                            int xthing = (int)(i * 7.5) + (int)t_PotentialHit.X;
                            total += t[xthing];
                        }
                        total /= 21;
                        t_PotentialHit.Y = total;
                        Game1.Instance.CenterOn(t_PotentialHit, true);
                    }
                    if (FiringVelocity >= 45.0f || Parent is FlameThrower)
                    {
                        Random rand = new Random();
                        if (!PInput.Instance.IsHuman(p_PlayerIndex))
                        {
                            if (NetworkManager.IsUsed)
                            {

                            }
                            else
                            {
                                float jitter = (float)(rand.NextDouble() * (3.0 * DegreeInRadians) - (1.5 * DegreeInRadians));
                                (Parent[ComponentType.Game_Rotation] as Game_Rotation).Rotation += jitter;
                            }
                        }
                        if (NetworkManager.IsUsed)
                        {
                            if ((Game1.Instance.GameManager as GameManagerTeamedInterface).MyMachineIsActive())
                            {
                                PacketWriter pw = new PacketWriter();
                                pw.Write(NetworkManager.INT);
                                pw.Write((int)(Parent as WeaponObject).Player.GetFacing());
                                pw.Write(NetworkManager.VECTOR2);
                                pw.Write((Vector2)(Parent as WeaponObject).Player.Position());
                                pw.Write(NetworkManager.DOUBLE);
                                pw.Write((double)(Parent[ComponentType.Game_Rotation] as Game_Rotation).Rotation);
                                pw.Write(NetworkManager.DOUBLE);
                                pw.Write((double)FiringVelocity);
                                NetworkManager.Instance.SendToAll(pw);
                            }
                            else
                            {
                                ((Parent as WeaponObject).Player[ComponentType.Game_Facing] as Game_Facing).Facing = (Facing)(int)NetworkManager.Instance.GetNextToken<Int32>();
                                ((Parent as WeaponObject).Player[ComponentType.Game_Position] as Game_Position).Position = (Vector2)NetworkManager.Instance.GetNextToken<Vector2>();
                                (Parent[ComponentType.Game_Rotation] as Game_Rotation).Rotation = (float)NetworkManager.Instance.GetNextToken<Double>();
                                FiringVelocity = (float)(double)NetworkManager.Instance.GetNextToken<Double>();
                            }
                        }
                        _CanShoot = false;
                        PoweringShot = false;
                        Done();
                        (Parent as WeaponObject).Fire(FiringVelocity);
                        FiringVelocity = 0.0f;
                    }
                }
                else if (PoweringShot)
                {
                    Random rand = new Random();
                    if (!PInput.Instance.IsHuman(p_PlayerIndex))
                    {
                        if (NetworkManager.IsUsed)
                        {
                            // Don't jitter if we are in a network game 
                            // because we can't determine that the jitter 
                            // will be the same client and server..
                            //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
                            // actually we could probably write the jitter if
                            // its our turn, and read the jitter if its not
                            // and that would probably work...
                            // if we knew whos turn it was
                        }
                        else
                        {
                            float jitter = (float)(rand.NextDouble() * (3.0 * DegreeInRadians) - (1.5 * DegreeInRadians));
                            (Parent[ComponentType.Game_Rotation] as Game_Rotation).Rotation += jitter;
                        }
                    }
                    if (NetworkManager.IsUsed)
                    {
                        if ((Game1.Instance.GameManager as GameManagerTeamedInterface).MyMachineIsActive())
                        {
                            PacketWriter pw = new PacketWriter();
                            pw.Write(NetworkManager.INT);
                            pw.Write((int)(Parent as WeaponObject).Player.GetFacing());
                            pw.Write(NetworkManager.VECTOR2);
                            pw.Write((Vector2)(Parent as WeaponObject).Player.Position());
                            pw.Write(NetworkManager.DOUBLE);
                            pw.Write((double)(Parent[ComponentType.Game_Rotation] as Game_Rotation).Rotation);
                            pw.Write(NetworkManager.DOUBLE);
                            pw.Write((double)FiringVelocity);
                            NetworkManager.Instance.SendToAll(pw);
                        }
                        else
                        {
                            ((Parent as WeaponObject).Player[ComponentType.Game_Facing] as Game_Facing).Facing = (Facing)(int)NetworkManager.Instance.GetNextToken<Int32>();
                            ((Parent as WeaponObject).Player[ComponentType.Game_Position] as Game_Position).Position = (Vector2)NetworkManager.Instance.GetNextToken<Vector2>();
                            (Parent[ComponentType.Game_Rotation] as Game_Rotation).Rotation = (float)NetworkManager.Instance.GetNextToken<Double>();
                            FiringVelocity = (float)(double)NetworkManager.Instance.GetNextToken<Double>();
                        }
                    }
                    _CanShoot = false;
                    PoweringShot = false;
                    Done();
                    (Parent as WeaponObject).Fire(FiringVelocity);
                    FiringVelocity = 0.0f;
                }
            }
        }

#if !ZUNE
        public override void ProcessKeyboard()
        {
            bool QPressed = PInput.Instance.Keyboard.Q.SinglePress;
            if (QPressed && !shooting)
            {
                bool HasAmmoForWeapon = false;
                {
                    WeaponObject weapon  = (Parent as WeaponObject);
                    AvailableWeaponList weaponlist = (Game1.Instance.GameManager as GameManagerTeamedInterface).CurrentUTP().AvailableWeapons;
                    HasAmmoForWeapon = !(0 == weaponlist.GetAvailable(weapon));
                }

                if (!HasAmmoForWeapon)
                {
                    Game1.Instance.AddMenu(new WeaponSelectionScreen((Parent as WeaponObject).Player));
                }
                else
                {
                    //deploy launching rod
                    if (((Parent as WeaponObject).Player[ComponentType.Game_Facing] as Game_Facing).Facing == Facing.Left)
                    {
                        ((Parent as WeaponObject).Player[ComponentType.Drawable_Sprite_Animated] as Drawable_Sprite_Animated).SetCurrentAnimation("ShootLeft", "AimLeft");
                        (Parent as WeaponObject).SetFacing(Facing.Left);
                    }
                    if (((Parent as WeaponObject).Player[ComponentType.Game_Facing] as Game_Facing).Facing == Facing.Right)
                    {
                        ((Parent as WeaponObject).Player[ComponentType.Drawable_Sprite_Animated] as Drawable_Sprite_Animated).SetCurrentAnimation("ShootRight", "AimRight");
                        (Parent as WeaponObject).SetFacing(Facing.Right);
                    }
                    shooting = true;
                    if ((Parent as WeaponObject).HasRod)
                    {
                        (Parent as WeaponObject).Rod = new LaunchingRod((Parent as WeaponObject).Player);
                        Game1.Instance.GameManager.AddToSceneGraph((Parent as WeaponObject).Rod);
                    }
                    (Game1.Instance.GameManager as GameManagerTeamedInterface).SetCanChangeTeam(false);
                    EventManager.GetInstance().AddEvent(ShowLauncher, 0.8f);
                    ((Parent as WeaponObject).Player[ComponentType.Holder_Weapon] as Holder_Weapon).Deploying = true;

                    Game1.Instance.CenterOn((Parent as WeaponObject).Player.Position());
                }
            }
            else if (QPressed && Shooting && !PoweringShot)
            {
                Done();
            }
            else if (shooting)
            {
                if (PInput.Instance.Keyboard.S.State == InputWrapper.ButtonState.Held && !PoweringShot)
                {
                    if ((Parent[ComponentType.Game_Facing] as Game_Facing).Facing == Facing.Right)
                    {
                        (Parent[ComponentType.Game_Rotation] as Game_Rotation).Rotation += .10f;
                        if ((Parent[ComponentType.Game_Rotation] as Game_Rotation).Rotation >= 1.5)
                        {
                            (Parent[ComponentType.Game_Rotation] as Game_Rotation).Rotation = 1.5f;
                        }
                    }
                    if ((Parent[ComponentType.Game_Facing] as Game_Facing).Facing == Facing.Left)
                    {
                        (Parent[ComponentType.Game_Rotation] as Game_Rotation).Rotation -= .10f;
                        if ((Parent[ComponentType.Game_Rotation] as Game_Rotation).Rotation <= -1.5)
                        {
                            (Parent[ComponentType.Game_Rotation] as Game_Rotation).Rotation = -1.5f;
                        }
                    }
                }
                if (PInput.Instance.Keyboard.W.State == InputWrapper.ButtonState.Held && !PoweringShot)
                {
                    if ((Parent[ComponentType.Game_Facing] as Game_Facing).Facing == Facing.Right)
                    {
                        (Parent[ComponentType.Game_Rotation] as Game_Rotation).Rotation -= .10f;
                        if ((Parent[ComponentType.Game_Rotation] as Game_Rotation).Rotation <= -1.5)
                        {
                            (Parent[ComponentType.Game_Rotation] as Game_Rotation).Rotation = -1.5f;
                        }
                    }
                    if ((Parent[ComponentType.Game_Facing] as Game_Facing).Facing == Facing.Left)
                    {
                        (Parent[ComponentType.Game_Rotation] as Game_Rotation).Rotation += .10f;
                        if ((Parent[ComponentType.Game_Rotation] as Game_Rotation).Rotation >= 1.5)
                        {
                            (Parent[ComponentType.Game_Rotation] as Game_Rotation).Rotation = 1.5f;
                        }
                    }
                }
                if (PInput.Instance.Keyboard.Space.State == InputWrapper.ButtonState.Held)
                {
                    FiringVelocity += .10f;
                    PoweringShot = true;
                    {
                        Vector2 t_PotentialHit = (Parent[ComponentType.Game_Position] as Game_Position).Position;
                        Terrain t = Game1.Instance.GameManager.Terrain;
                        Vector2 t_gravity = GravityManager.Instance.Gravity;
                        Vector2 t_power = Vector2.Zero;
                        {
                            Facing t_f = (Parent[ComponentType.Game_Facing] as Game_Facing).Facing;
                            float angle = (Parent[ComponentType.Game_Rotation] as Game_Rotation).Rotation;
                            if (t_f == Facing.Right)
                            {
                                t_power = new Vector2((float)FiringVelocity * (float)Math.Cos(angle), (float)FiringVelocity * (float)Math.Sin(angle));
                            }
                            if (t_f == Facing.Left)
                            {
                                t_power = new Vector2((float)-FiringVelocity * (float)Math.Cos(angle), (float)-FiringVelocity * (float)Math.Sin(angle));
                            }
                        }
                        if(t_PotentialHit.X >= 1920)
                        {
                            t_PotentialHit.X = 1910;
                        }
                        while(t[(int)t_PotentialHit.X] > t_PotentialHit.Y)
                        {
                            t_power += t_gravity;
                            t_PotentialHit += t_power;
                        }
                        int total = 0;
                        for (int i = -15; i <= 15; ++i)
                        {
                            int xthing = (int)i + (int)t_PotentialHit.X;
                            if(xthing >= 1920)
                            {
                                xthing = 1910;
                            }
                            total += t[xthing];
                        }
                        total /= 31;
                        t_PotentialHit.Y = total;
                        Game1.Instance.CenterOn(t_PotentialHit);
                    }
                }
                else if (PoweringShot)
                {
                    Random rand = new Random();
                    _CanShoot = false;
                    PoweringShot = false;
                    Done();
                    (Parent as WeaponObject).Fire(FiringVelocity);
                    FiringVelocity = 0.0f;
                }
            }
        }
#endif

        protected void ShowLauncher()
        {
            if (shooting)
            {
                ((Parent as WeaponObject).Player[ComponentType.Holder_Weapon] as Holder_Weapon).Deploying = false;
                (Game1.Instance.GameManager as GameManagerTeamedInterface).SetCanChangeTeam(false);
                ((Parent as WeaponObject).Player[ComponentType.Holder_Weapon] as Holder_Weapon).IsActive = shooting;
            }
        }

        void Done()
        {
            ((Parent as WeaponObject).Player[ComponentType.Holder_Weapon] as Holder_Weapon).IsActive = false;
            shooting = false;
            (Game1.Instance.GameManager as GameManagerTeamedInterface).SetCanChangeTeam(true);
            if (((Parent as WeaponObject).Player[ComponentType.Game_Facing] as Game_Facing).Facing == Facing.Left)
            {
                ((Parent as WeaponObject).Player[ComponentType.Drawable_Sprite_Animated] as Drawable_Sprite_Animated).SetCurrentAnimation("IdleLeft", "IdleLeft");
            }
            if (((Parent as WeaponObject).Player[ComponentType.Game_Facing] as Game_Facing).Facing == Facing.Right)
            {
                ((Parent as WeaponObject).Player[ComponentType.Drawable_Sprite_Animated] as Drawable_Sprite_Animated).SetCurrentAnimation("IdleRight","IdleRight");
            }
            if ((Parent as WeaponObject).HasRod)
            {
                Game1.Instance.GameManager.RemoveFromSceneGraph((Parent as WeaponObject).Rod);
                (Parent as WeaponObject).Rod = null;
            }
        }

        public override void Init()
        {
            base.Init();
        }
    }
}
